from requests.packages.urllib3.exceptions import InsecureRequestWarning

# !usr/bin/env python
# -*- coding:utf-8 -*-
"""
@author: lenovo by XYF
@file: amidoufu.py
@time: 2020/03/10
@function: 
"""
import requests
import json
import time
import os
import re
import ssl
import fileinput
import sys
import random
import threading
import pygame
import configparser
import tkinter.messagebox
from tkinter import *
from selenium import webdriver

ssl._create_default_https_context = ssl._create_unverified_context

INFO = {
    "name": "快手用户批量下载",
    "author": "阿米豆腐丶",
    "repository": "最初版本oGsLP提供,最初源码下载地址:www.github.com/oGsLP/kuaishou-crawler",
    "version": "0.0.2",
    "publishDate": "20-05-06"
}

PROFILE_URL = "https://live.kuaishou.com/profile/"
DATA_URL = "https://live.kuaishou.com/m_graphql"
WORK_URL = "https://v.kuaishou.com/fw/photo/"




__param_did = ""

__headers_web = {
    'accept': '*/*',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7',
    'Connection': 'keep-alive',
    'Content-Type': 'application/json',
    'Host': 'live.kuaishou.com',
    'Origin': 'https://live.kuaishou.com',
    'Sec-Fetch-Mode': 'cors',
    'Sec-Fetch-Site': 'same-origin',
    # User-Agent/Cookie 根据自己的电脑修改
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
    'Cookie': ''
}
__headers_mobile = {
    'accept': '*/*',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-cn',
    'Connection': 'close',
    'Host': 'v.kuaishou.com',
    'User-Agent': 'Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL00 Build/HUAWEIBLA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36',
    'Cookie': ''
}
__headers_Requests_web = {
    'accept': '*/*',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7',
    'Connection': 'keep-alive',
    'Host': 'v.kuaishou.com',
    'Upgrade-Insecure-Requests': '1',
    # User-Agent/Cookie 根据自己的电脑修改
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36',
    'Cookie': ''
}
# User-Agent': 'Mozilla/5.0 (Linux; U; Android 8.1.0; zh-cn; BLA-AL00 Build/HUAWEIBLA-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.9 Mobile Safari/537.36

class QJ:
    exists = 0
    stop = False
    userid_cook = ""


exists = 0
click_access = 0
xiladaili = ""
bakuid = ""
__doufu_list = []

__date_cache = ""
__date_pic_count = 0



def __init__():
    #print(var.get())
    if QJ.userid_cook != "":
        thread_it(doufu(),)
    else:
        thread_it(__intro(),)

def set_did(did, did2, did3, did4, did5):
    __param_did = did
    # __param_did1 = did1
    __param_did2 = did2
    __param_did3 = did3
    __param_did4 = did4
    __param_did5 = did5
    # __param_did3 = did3
    __headers_web[
        'Cookie'] = 'did=' + did + ';userId=' + did5 + ';kuaishou.live.web_st=' + did2 + ';kuaishou.live.web_ph=' + did3 + ';kuaishou.live.bfb1s=' + did4
    __headers_mobile['Cookie'] = 'did=' + did + ';userId=' + did5 + ';didv=' + str(int(time.time()) * 1000)
    #print("用户cookie的值：" + 'did=' + did + ';userId=' + did5 + ';kuaishou.live.web_st=' + did2 + ';kuaishou.live.web_ph=' + did3 + ';kuaishou.live.bfb1s=' + did4)
    # text.insert(END,"初始化成功...")
    # text.update()
    # text.see(END)
    text.insert(END, "用户cookie的值：" + 'did=' + did + ';userId=' + did5 + ';kuaishou.live.web_st=' + did2 + ';kuaishou.live.web_ph=' + did3 + ';kuaishou.live.bfb1s=' + did4)
    text.update()
    text.see(END)
    if click_access != 1:
        thread_it(doufu(), )
    else:
        thread_it(one_click_access2(), )
    # __headers_web['Cookie'] = 'did=' + did + ';kuaishou.live.web_ph=' + did1 + ';kuaishou.live.web_st=' + did2 + ';kuaishou.live.bfb1s=' + did3 +';didv=' + str(int(time.time())*1000) + ';userId='
    # __headers_mobile['Cookie'] = 'did=' + did + ';kuaishou.live.web_ph=' + did1 + ';kuaishou.live.web_st=' + did2 + ';kuaishou.live.bfb1s=' + did3 +';didv=' + str(int(time.time())*1000) + ';userId='
    # print("用户cookie的值：" + 'did=' + did + ';kuaishou.live.web_ph=' + did1 + ';kuaishou.live.web_st=' + did2 + ';kuaishou.live.bfb1s=' + did3 +';didv=' + str(int(time.time())*1000) + ';userId=')
    # print(__headers_mobile['Cookie'])




def doufu():
    __read_preset()
    time.sleep(3)
    latetime = int(entry.get())
    #print("")
    text.insert(END, "")
    text.update()
    text.see(END)
    #print("延时时间:" + latetime)
    text.insert(END,"延时时间:" + str(latetime))
    text.update()
    text.see(END)
    #print("")
    text.insert(END, "")
    text.update()
    text.see(END)
    #print("准备开始爬取，共有%d个用户..." % len(__doufu_list))
    text.insert(END,"准备开始爬取，共有%d个用户..." % len(__doufu_list))
    text.update()
    text.see(END)
    print()
    time.sleep(3)
    for uid in __doufu_list:
        # print(uid)
        global bakuid
        bakuid = uid
        # print(bakuid)
        __date_cache = ""
        __date_count = 0
        if "kuaishou" in uid:  # kuaishouapp.com
            if "/profile" in uid:
                recovery3 = uid
                recovery_list = recovery3.split("/")
                uid1 = recovery_list[4]
                #print("Short chain:" + uid + "丨Uid:" + uid1)
                text.insert(END,"Short chain1:" + uid + "丨Uid:" + uid1)
                text.update()
                text.see(END)
                time.sleep(3)
                __doufu_user(uid1, latetime)
            else:
                r = requests.get(uid, headers=__headers_Requests_web)
                # print(r.history)
                reditList = r.history  # 可以看出获取的是一个地址序列
                # print(f'获取重定向的历史记录：{reditList}')
                # print(f'获取第一次重定向的headers头部信息：{reditList[0].headers}')
                # print(f'获取重定向最终的url：{reditList[len(reditList) - 1].headers["location"]}')
                recovery1 = reditList
                recovery2 = reditList[0].headers
                recovery3 = reditList[len(reditList) - 1].headers["location"]
                recovery_list = recovery3.split("/")
                uid1 = recovery_list[4]
                #print("Short chain:" + uid + "丨Uid:" + uid1)
                text.insert(END, "Short chain2:" + uid + "丨Uid:" + uid1)
                text.update()
                text.see(END)
                # print(recovery_list[4])
                # print(recovery3)
                __doufu_user(uid1, latetime)
        else:
            #print("Uid:" + uid)
            text.insert(END, "丨Uid:" + uid)
            text.update()
            text.see(END)
            __doufu_user(uid, latetime)


def add_to_list(uid):
    __doufu_list.append(uid)


def __doufu_user(uid, latetime):
    if uid.isdigit():
        uid = __switch_id(uid)

    payload = {"operationName": "privateFeedsQuery",
               "variables": {"principalId": uid, "pcursor": "", "count": 99999},
               "query": "query privateFeedsQuery($principalId: String, $pcursor: String, $count: Int) {\n  privateFeeds(principalId: $principalId, pcursor: $pcursor, count: $count) {\n    pcursor\n    list {\n      id\n      thumbnailUrl\n      poster\n      workType\n      type\n      useVideoPlayer\n      imgUrls\n      imgSizes\n      magicFace\n      musicName\n      caption\n      location\n      liked\n      onlyFollowerCanComment\n      relativeHeight\n      timestamp\n      width\n      height\n      counts {\n        displayView\n        displayLike\n        displayComment\n        __typename\n      }\n      user {\n        id\n        eid\n        name\n        avatar\n        __typename\n      }\n      expTag\n      __typename\n    }\n    __typename\n  }\n}\n"}
    # payload = {"operationName": "privateFeedsQuery",
    #            "variables":{"principalId":uid,"pcursor":"","count":99999},
    #            "query": "query privateFeedsQuery($principalId: String, $pcursor: String, $count: Int) {\n  privateFeeds(principalId: $principalId, pcursor: $pcursor, count: $count) {\n    pcursor\n    list {\n      id\n      thumbnailUrl\n      poster\n      workType\n      type\n      useVideoPlayer\n      imgUrls\n      imgSizes\n      magicFace\n      musicName\n      caption\n      location\n      liked\n      onlyFollowerCanComment\n      relativeHeight\n      timestamp\n      width\n      height\n      counts {\n        displayView\n        displayLike\n        displayComment\n        __typename\n      }\n      user {\n        id\n        eid\n        name\n        avatar\n        __typename\n      }\n      expTag\n      __typename\n    }\n    __typename\n  }\n}\n"}
    res = requests.post(DATA_URL, headers=__headers_web, json=payload)
    # print(uid)
    # print(res.text)
    works = json.loads(res.content.decode(encoding='utf-8', errors='strict'))['data']['privateFeeds']['list']

    if works != []:
        if not os.path.exists("./快手data"):
            os.makedirs("./快手data")

        # 这两行代码将response写入json供分析
        # with open("data/" + uid + ".json", "w") as fp:
        #     fp.write(json.dumps(works, indent=2))

        # 防止该用户在直播，第一个作品默认为直播，导致获取信息为NoneType
        # print(works)
        if works[0]['id'] is None:
            works.pop(0)
        name = re.sub(r'[\\/:*?"<>|\r\n]+', "", works[0]['user']['name'])
        dir = "快手data/" + name + "(" + uid + ")/"
        # print(len(works))
        if not os.path.exists(dir):
            os.makedirs(dir)

        # if not os.path.exists(dir + ".list"):
        # print("")

        #print("开始爬取用户 " + name + "，保存在目录 " + dir)
        text.insert(END,"开始爬取用户 " + name + "，保存在目录 " + dir)
        text.update()
        text.see(END)
        #print(" 共有" + str(len(works)) + "个作品")
        text.insert(END," 共有" + str(len(works)) + "个作品")
        text.update()
        text.see(END)
        #print("")
        text.insert(END,"")
        text.update()
        text.see(END)
        time.sleep(1)

        if not os.path.exists(dir + "图集/"):
            photos = 0
        else:
            photos = len(
                [lists for lists in os.listdir(dir + "图集/") if os.path.isdir(os.path.join(dir + "图集/", lists))])

        if not os.path.exists(dir + "视频/"):
            videos = 0
        else:
            videos = len(
                [lists for lists in os.listdir(dir + "视频/") if os.path.isfile(os.path.join(dir + "视频/", lists))])

        allnumber = photos + videos
        #print("丨用户:" + name + "丨")
        text.insert(END,"丨用户:" + name + "丨" )
        text.update()
        text.see(END)
        #print("丨当前电脑共有" + "丨视频:" + str(videos) + "个丨图集:" + str(photos) + "个丨总共作品数:" + str(allnumber) + "丨")
        text.insert(END, "丨当前电脑共有" + "丨视频:" + str(videos) + "个丨图集:" + str(photos) + "个丨总共作品数:" + str(allnumber) + "丨")
        text.update()
        text.see(END)
        #print("")
        text.insert(END,"" )
        text.update()
        text.see(END)
        time.sleep(1)

        # print(allnumber)
        # print(len(works))

        if allnumber == len(works):
            #print("用户 " + name + "视频没有更新!")
            text.insert(END,"用户 " + name + "视频没有更新!" )
            text.update()
            text.see(END)
            #print("")
            text.insert(END, "")
            text.update()
            text.see(END)
            time.sleep(1)

        if allnumber != len(works):
            with open("list_num.txt", "r+") as l_num:
                lnm_text = l_num.read()
                # print(lnm_text)
                lum_list = lnm_text.split("丨")
                lum_uid = lum_list[1]
                # print(lum_uid)
                lum_num = int(lum_list[3])
                # print(lum_num)

            if lum_uid == bakuid:
                #print("上次记录:" + "Uid or Short chain丨" + bakuid + "丨第丨" + str(lum_num + 1) + "丨个视频")
                text.insert(END, "上次记录:" + "Uid or Short chain丨" + bakuid + "丨第丨" + str(lum_num + 1) + "丨个视频")
                text.update()
                text.see(END)
                allnumber = 0
                #print("")
                text.insert(END, "")
                text.update()
                text.see(END)
            else:
                #print("新的开始:" + "Uid or Short chain丨" + bakuid + "丨第丨0丨个视频")
                text.insert(END, "新的开始:" + "Uid or Short chain丨" + bakuid + "丨第丨0丨个视频")
                text.update()
                text.see(END)
                with open("list_num.txt", "w") as l_num_w:
                    l_num_w.write("Uid or Short chain丨" + bakuid + "丨第丨0丨个视频")
                lum_num = 0
                allnumber = 0
                #print("")
                text.insert(END, "")
                text.update()
                text.see(END)

            for j in range(lum_num, len(works)):
                for line in fileinput.input("list_num.txt", inplace=1):
                    if not fileinput.isfirstline():
                        print(fileinput.replace("\n", ""))

                # " + "丨"+ name + "
                # print("丨用户:" + name)
                # print("丨下载信息如下:丨")
                # print("丨总下载数:" + str(len(works)) + "个丨" + "当前下载数:" + str(j) + "个丨" + "等待下载数:" + str(len(works) - j) + "个丨")
                # print("丨当前电脑共有作品数:" + str(allnumber) + "丨视频:" + str(videos) + "个丨图集:" + str(photos) + "个丨")
                # print("")

                if allnumber >= len(works):
                    break
                else:
                    if QJ.stop == True:
                        text.insert(END, "成功跳过当前用户...")
                        text.update()
                        text.see(END)
                        break
                    __doufu_work(uid, dir, works[j], j + 1)
                    if not os.path.exists(dir + "图集/"):
                        photos = 0
                    else:
                        photos = len([lists for lists in os.listdir(dir + "图集/") if
                                      os.path.isdir(os.path.join(dir + "图集/", lists))])

                    if not os.path.exists(dir + "视频/"):
                        videos = 0
                    else:
                        videos = len([lists for lists in os.listdir(dir + "视频/") if
                                      os.path.isfile(os.path.join(dir + "视频/", lists))])

                    allnumber = photos + videos
                    #print("丨用户:" + name + "丨")
                    text.insert(END,"丨用户:" + name + "丨" )
                    text.update()
                    text.see(END)
                    #print("丨下载信息如下:丨")
                    text.insert(END,"丨下载信息如下:丨" )
                    text.update()
                    text.see(END)
                    #print("丨总下载数:" + str(len(works)) + "个丨" + "当前下载数:" + str(j + 1) + "个丨" + "等待下载数:" + str(len(works) - j - 1) + "个丨")
                    text.insert(END,"丨总下载数:" + str(len(works)) + "个丨" + "当前下载数:" + str(j + 1) + "个丨" + "等待下载数:" + str(len(works) - j - 1) + "个丨" )
                    text.update()
                    text.see(END)
                    #print("丨当前电脑共有作品数:" + str(allnumber) + "丨视频:" + str(videos) + "个丨图集:" + str(photos) + "个丨")
                    text.insert(END,"丨当前电脑共有作品数:" + str(allnumber) + "丨视频:" + str(videos) + "个丨图集:" + str(photos) + "个丨" )
                    text.update()
                    text.see(END)
                    #print("")
                    text.insert(END, "")
                    text.update()
                    text.see(END)
                    if var.get() == 1:
                        if QJ.exists == int(entry2.get()):
                            text.insert(END, "正在自动跳过当前用户...")
                            text.update()
                            text.see(END)
                            break
                # print(j)
                # print(__headers_mobile['Cookie'])
                time.sleep(int(latetime))
            #print("")
            text.insert(END, "")
            text.update()
            text.see(END)


            if not os.path.exists(dir + "图集/"):
                photos = 0
            else:
                photos = len(
                    [lists for lists in os.listdir(dir + "图集/") if os.path.isdir(os.path.join(dir + "图集/", lists))])

            if not os.path.exists(dir + "视频/"):
                videos = 0
            else:
                videos = len([lists for lists in os.listdir(dir + "视频/") if
                              os.path.isfile(os.path.join(dir + "视频/", lists))])

            allnumber = photos + videos
            #print("")
            text.insert(END, "")
            text.update()
            text.see(END)
            #print("丨用户:" + name + "丨")
            text.insert(END,"丨用户:" + name + "丨" )
            text.update()
            text.see(END)
            #print("丨当前电脑共有" + "丨视频:" + str(videos) + "个丨图集:" + str(photos) + "个丨总共作品数:" + str(allnumber) + "丨")
            text.insert(END, "丨当前电脑共有" + "丨视频:" + str(videos) + "个丨图集:" + str(photos) + "个丨总共作品数:" + str(allnumber) + "丨")
            text.update()
            text.see(END)
            #print("")
            text.insert(END, "")
            text.update()
            text.see(END)
            #print("用户 " + name + "视频爬取完成!")
            text.insert(END,"用户 " + name + "视频爬取完成!" )
            text.update()
            text.see(END)

        #print("")
        text.insert(END, "")
        text.update()
        text.see(END)
        time.sleep(1)
        #print("等待3秒执行下一个")
        text.insert(END, "等待3秒执行下一个")
        text.update()
        text.see(END)
        for line in fileinput.input("list_num.txt", inplace=1):
            if not fileinput.isfirstline():
                print(fileinput.replace("\n", ""))
        time.sleep(1)
        #print("等待2秒执行下一个")
        text.insert(END, "等待2秒执行下一个")
        text.update()
        text.see(END)
        time.sleep(1)
        s_w = open("list_num.txt", "w")
        s_w.write("Uid or Short chain丨0丨第丨0丨个视频")
        s_w.close()
        time.sleep(1)
        #print("等待1秒执行下一个")
        text.insert(END, "等待1秒执行下一个")
        text.update()
        text.see(END)
        QJ.stop = False
        with open("uid_log.txt", "r+") as f:
            # print(bakuid)
            p = re.compile(bakuid)
            lines = [line for line in f.readlines() if p.search(line) is None]
            fd = open("uid_log.txt", "w")
            fd.seek(0)
            fd.truncate(0)
            fd.writelines(lines)
            fd.close()
        time.sleep(1)
        #print("")
        text.insert(END, "")
        text.update()
        text.see(END)
        QJ.exists = 0
    else:
        text.insert(END, "")
        text.update()
        text.see(END)
        text.insert(END, "UID不存在或者已经被封,获取下一个")
        text.update()
        text.see(END)
        text.insert(END, "")
        text.update()
        text.see(END)
        with open("uid_log.txt", "r+") as f:
            # print(bakuid)
            p = re.compile(bakuid)
            lines = [line for line in f.readlines() if p.search(line) is None]
            fd = open("uid_log.txt", "w")
            fd.seek(0)
            fd.truncate(0)
            fd.writelines(lines)
            fd.close()

    # lines = [l for l in open("uid.txt", "r") if l.find(uid, 0, 8) != 0]
    # fd = open("uid_log.txt", "w")
    # fd.writelines(lines)
    # fd.close()

    # print(path_list)

    # with open("a.txt", "r+") as f:
    #     p = re.compile("gmail|aol|yahoo")
    #     lines = [line for line in f.readlines() if p.search(line) is None]
    #     f.seek(0)
    #     f.truncate(0)
    #     f.writelines(lines)

    # list = []
    # matchPattern = re.compile(uid)
    # f_path = r'uid.txt'
    # with open(f_path)as f:
    #     while 1:
    #         line = f.readline()
    #         if not line:
    #             break
    #         elif matchPattern.search(line):
    #             pass
    #         else:
    #             list.append(line)
    #     f.close()
    #     f = open('uid_log.txt', 'w')
    #     for i in list:
    #         f.write(i)
    #     f.close()

    '''
    快手分为五种类型的作品，在作品里面表现为workType属性
     * 其中两种图集: `vertical`和`multiple`，意味着拼接长图和多图，所有图片的链接在imgUrls里
     * 一种单张图片: `single` 图片链接也在imgUrls里
     * K歌: `ksong` 图片链接一样，不考虑爬取音频...
     * 视频: `video` 需要解析html获得视频链接
    '''


def __doufu_work(uid, dir, work, wdx):
    s_w = open("list_num.txt", "w")
    s_w.write("Uid or Short chain丨" + bakuid + "丨第丨" + str(int(wdx - 1)) + "丨个视频")
    s_w.close()
    w_type = work['workType']
    w_caption = re.sub(r"\s+", " ", work['caption'])
    w_name = re.sub(r'[\\/:*?"<>|\r\n]+', "", w_caption)[0:24]
    w_time = time.strftime('%Y年%m月%d日%H时%M分%S秒', time.localtime(work['timestamp'] / 1000))
    w_index = ""
    global __date_cache
    global __date_count
    if __date_cache == w_time:
        __date_count = __date_count + 1
        if __date_count > 0:
            w_index = "(%d)" % __date_count
    else:
        __date_cache = w_time
        __date_count = 0

    if w_type == 'vertical' or w_type == 'multiple' or w_type == "single" or w_type == 'ksong':
        w_urls = work['imgUrls']
        l = len(w_urls)
        #print("  " + str(wdx) + ")图集作品：" + w_caption + "，" + "共有" + str(l) + "张图片")
        text.insert(END,"  " + str(wdx) + ")图集作品：" + w_caption + "，" + "共有" + str(l) + "张图片")
        text.update()
        text.see(END)
        for i in range(l):
            p_name = w_time + "_" + work['id'] + "_" + w_name + "_" + str(i + 1) + '.jpg'
            w_name2 = re.sub(r'[.*?"<>|\r\n]+', "", w_name)
            dir2 = dir + "图集/" + w_time + "_" + work['id']  + "_" + w_name2 + "/"
            if not os.path.exists(dir2):
                os.makedirs(dir2)
            pic = dir2 + p_name
            if not os.path.exists(pic):
                r = requests.get(w_urls[i].replace("webp", "jpg"))
                r.raise_for_status()
                with open(pic, "wb") as f:
                    f.write(r.content)
                #print("    " + str(i + 1) + "/" + str(l) + " 图片 " + p_name + " 下载成功 √")
                text.insert(END, "    " + str(i + 1) + "/" + str(l) + " 图片 " + p_name + " 下载成功 √")
                text.update()
                text.see(END)
                text.insert(END, "图集地址:")
                text.update()
                text.see(END)
                text.insert(END, w_urls[i])
                text.update()
                text.see(END)
            else:
                #print("    " + str(i + 1) + "/" + str(l) + " 图片 " + p_name + " 已存在 √")
                text.insert(END, "    " + str(i + 1) + "/" + str(l) + " 图片 " + p_name + " 已存在 √")
                text.update()
                text.see(END)
    elif w_type == 'video':
        v_name = w_time + "_" + work['id'] + "_" + w_name + ".mp4"
        dir2 = dir + "视频/"
        video = dir2 + v_name
        if os.path.exists(video):
            #print("    视频 " + v_name + " 已存在 √")
            text.insert(END, "    视频 " + v_name + " 已存在 √")
            text.update()
            text.see(END)
            QJ.exists += 1
            print(bakuid + "已存在出现了" + str(QJ.exists) + "次")
        else:
            QJ.exists = 0
            w_url = WORK_URL + work['id']
            res = requests.get(w_url, headers=__headers_mobile, timeout=30,
                               params={"fid": int(QJ.userid_cook), "cc": "share_copylink",
                                       "shareId": "143108986354"})
            # print(QJ.userid_cook)
            # print(proxies)
            requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
            # print(res.text)

            # payload1 = {"operationName": "SharePageQuery",
            #            "variables": {"photoId": work['id'], "principalId": uid},
            #            "query": "query SharePageQuery($principalId: String, $photoId: String) {\n  feedById(principalId: $principalId, photoId: $photoId) {\n    currentWork {\n      playUrl\n      __typename\n    }\n    __typename\n  }\n}\n"}
            # res1 = requests.post(DATA_URL, headers=__headers_web, json=payload1)
            # html1 = json.loads(res1.content.decode(encoding='utf-8', errors='strict'))['data']['feedById']['currentWork']
            # v_url = html1['playUrl']
            # print(v_url)

            html = res.text
            waitreplace = work['id'] + '&#34.*?&#34;srcNoMark&#34;:&#34;(.*?)&#34;'

            # print(html)
            # print(html.find('快手验证码'))
            if html.find('操作太快了，请稍微休息一下') != -1:
                #print("出现操作快了!!!")
                text.insert(END, "出现验证码了!!!可能触发反爬机制------60秒后程序自动重新运行!!!")
                text.update()
                text.see(END)
                time.sleep(60)
                restart_program()

                # print(res.text)

                # payload1 = {"operationName": "SharePageQuery",
                #            "variables": {"photoId": work['id'], "principalId": uid},
                #            "query": "query SharePageQuery($principalId: String, $photoId: String) {\n  feedById(principalId: $principalId, photoId: $photoId) {\n    currentWork {\n      playUrl\n      __typename\n    }\n    __typename\n  }\n}\n"}
                # res1 = requests.post(DATA_URL, headers=__headers_web, json=payload1)
                # html1 = json.loads(res1.content.decode(encoding='utf-8', errors='strict'))['data']['feedById']['currentWork']
                # v_url = html1['playUrl']
                # print(v_url)

                    # doufu()

            if html.find('快手验证码') != -1:
                text.insert(END, "出现验证码了!!!可能触发反爬机制------60秒后程序自动重新运行!!!")
                text.update()
                text.see(END)
                time.sleep(60)
                restart_program()


                    # doufu()

            v_url = re.findall(waitreplace, html)
            # print(html)
            # pattern = re.compile(r"playUrl", re.MULTILINE | re.DOTALL)
            # script = soup.find("script", text=pattern)
            # s = pattern.search(script.text).string
            # v_url = s.split('playUrl":"')[1].split('.mp4')[0].encode('utf-8').decode('unicode-escape') + '.mp4'
            try:
                #print("  " + str(wdx) + ")视频作品：" + "丨id" + work['id'] + "丨" + w_caption)
                text.insert(END, "  " + str(wdx) + ")视频作品：" + "丨" + w_time + "丨"  + work['id'] + "丨" + w_caption)
                text.update()
                text.see(END)
            except:
                #print("  这里似乎有点小错误，已跳过")
                text.insert(END, "  这里似乎有点小错误，已跳过")
                text.update()
                text.see(END)
            #v_name = w_time + w_index + "_" + w_name + ".mp4"
            v_name = w_time + "_" + work['id'] + "_" + w_name + ".mp4"
            dir2 = dir + "视频/"
            if not os.path.exists(dir2):
                os.makedirs(dir2)
            #video = dir2 + v_name
            video = dir2 + v_name

            if v_url:
                if not os.path.exists(video):
                    # r = requests.get(v_url)
                    r = requests.get(v_url[0])
                    r.raise_for_status()

                    with open(video, "wb") as f:
                        f.write(r.content)
                    #print("    视频 " + v_name + " 下载成功 √")
                    text.insert(END, "    视频 " + v_name + " 下载成功 √")
                    text.update()
                    text.see(END)
                    text.insert(END, "视频地址:")
                    text.update()
                    text.see(END)
                    text.insert(END, v_url[0])
                    text.update()
                    text.see(END)
                else:
                    #print("    视频 " + v_name + " 已存在 √")
                    text.insert(END, "    视频 " + v_name + " 已存在 √")
                    text.update()
                    text.see(END)
            else:
                #print("未找到视频")
                text.insert(END, "未找到视频-----60秒后程序自动重新运行!!!")
                text.update()
                text.see(END)
                time.sleep(60)
                restart_program()
                # doufu()
    else:
        #print("错误的类型")
        text.insert(END, "错误的类型-----60秒后程序自动重新运行!!!")
        text.update()
        text.see(END)
        time.sleep(60)
        restart_program()
        #doufu()


def __read_preset():
    p_path = "uid.txt"
    if not os.path.exists(p_path):
        #print("创建预设文件 uid ...")
        text.insert(END,"创建预设文件 uid ..." )
        text.update()
        text.see(END)
        open(p_path, "w")
    if not os.path.getsize(p_path):
        #print("请在预设文件 uid 中记录需要爬取的用户id，一行一个")
        text.insert(END,"请在预设文件 uid 中记录需要爬取的用户id，一行一个")
        text.update()
        text.see(END)
        exit(0)
    if not os.path.exists("uid_log.txt"):
        p_path = "uid.txt"
        r_w = open("uid.txt", "r+")
        s_w = open("uid_log.txt", "w")
        s_w.write(r_w.read())
    else:
        p_path = "uid_log.txt"
        with open("uid_log.txt", "r+") as q:
            if q.read() == "":
                r_w = open("uid.txt", "r+")
                q.write(r_w.read())
    if not os.path.exists("list_num.txt"):
        l_n = open("list_num.txt", "w")
        l_n.write("Uid or Short chain丨0丨第丨0丨个视频")
        l_n.close()
    else:
        with open("list_num.txt", "r+") as qq:
            if qq.read() == "":
                qq.write("Uid or Short chain丨0丨第丨0丨个视频")
    # print(p_path)
    with open("xiladaili.txt", "r+") as xila:
        global xiladaili
        xiladaili = xila.read()
    #print(p_path)
    with open(p_path, "r") as f:
        for line in f:
            if line[0] != "#":
                __doufu_list.append(line.strip())


def __switch_id(uid):
    payload = {"operationName": "SearchOverviewQuery",
               "variables": {"keyword": uid, "ussid": None},
               "query": "query SearchOverviewQuery($keyword: String, $ussid: String) {\n  pcSearchOverview(keyword: $keyword, ussid: $ussid) {\n    list {\n      ... on SearchCategoryList {\n        type\n        list {\n          categoryId\n          categoryAbbr\n          title\n          src\n          __typename\n        }\n        __typename\n      }\n      ... on SearchUserList {\n        type\n        ussid\n        list {\n          id\n          name\n          living\n          avatar\n          sex\n          description\n          counts {\n            fan\n            follow\n            photo\n            __typename\n          }\n          __typename\n        }\n        __typename\n      }\n      ... on SearchLivestreamList {\n        type\n        lssid\n        list {\n          user {\n            id\n            avatar\n            name\n            __typename\n          }\n          poster\n          coverUrl\n          caption\n          id\n          playUrls {\n            quality\n            url\n            __typename\n          }\n          quality\n          gameInfo {\n            category\n            name\n            pubgSurvival\n            type\n            kingHero\n            __typename\n          }\n          hasRedPack\n          liveGuess\n          expTag\n          __typename\n        }\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n}\n"}

    res = requests.post(DATA_URL, headers=__headers_web, json=payload)
    dt = json.loads(res.content.decode(encoding='utf-8', errors='strict'))['data']
    print(res.text)
    # with open("data/jj_" + uid + ".json", "w") as fp:
    #     fp.write(json.dumps(dt, indent=2))

    return dt['pcSearchOverview']['list'][1]['list'][0]['id']


def __openchrome():
    driver = webdriver.Chrome(executable_path="Google Chrome/chromedriver.exe")
    driver.get("https://live.kuaishou.com/v/hot/")
    time.sleep(1)
    driver.implicitly_wait(30)
    file = '提示音.wav'  # 文件名是完整路径名
    while driver.find_elements_by_tag_name("iframe") != []:
        text.insert(END, "出现验证码弹窗请手动验证" )
        text.update()
        text.see(END)
        pygame.mixer.init()  # 初始化音频
        track = pygame.mixer.music.load(file)  # 载入音乐文件
        pygame.mixer.music.play()  # 开始播放
        time.sleep(5)
        pygame.mixer.music.stop()  # 停止播放
        if driver.find_elements_by_tag_name("iframe") == []:
            pygame.mixer.music.stop()  # 停止播放
            break
    name = driver.find_element_by_xpath('//*[@id="app"]/div[1]/div[1]/header/div/div[2]/div[3]/a/span')
    name_title = name.get_attribute('title')
    # cookie= driver.get_cookies()
    while name_title == "":
        # print("你还没有登录,请登录!!!")
        text.insert(END, "你还没有登录,请登录!!!")
        text.update()
        text.see(END)
        driver.find_element_by_class_name("tip-container").click()
        time.sleep(1)
        driver.find_element_by_class_name("third-part-entry-qq").click()
        driver.close()
        time.sleep(1)
        driver.switch_to.window(driver.window_handles[0])
        driver.switch_to.frame(0)
        driver.find_element_by_class_name("nick").click()
        time.sleep(5)
        name = driver.find_element_by_xpath('//*[@id="app"]/div[1]/div[1]/header/div/div[2]/div[3]/a/span')
        name_title = name.get_attribute('title')
    # print("你已经登录,登录名:" + name_title)
    text.delete(0, END)
    text.insert(END, "你已经登录,登录名:" + name_title)
    text.update()
    text.see(END)
    cookie = driver.get_cookies()
    # driver.get("https://live.kuaishou.com/u/G338217245/3xjz7rnjnh6hjts")
    cookie = [item['value'] for item in driver.get_cookies()]
    cookie1 = [item['name'] for item in driver.get_cookies()]
    # cookie = [item['name'] + '=' + item['value'] for item in driver.get_cookies()]
    # print(cookie)
    # print(cookie1)
    param_did = cookie[4]
    # param_did1 = cookie[1]
    # param_did2 = cookie[2]
    # param_did3 = cookie[7]
    param_did2 = cookie[1]
    param_did3 = cookie[0]
    param_did4 = cookie[7]
    param_did5 = cookie[2]
    QJ.userid_cook = cookie[2]
    # param_kuaishou.live.web_st = cookie[1]
    driver.get("https://live.kuaishou.com/v/hot/")
    # param_did = "123"
    # print(driver.title)  # 在编辑器的终端可以看到网站的标题打印出来
    # driver.quit()  # 关闭Chrome浏览器，如果不写这句话浏览器就会停留在百度首页在后台运行不会关闭浏览器
    # driverOptions = webdriver.ChromeOptions()
    # driverOptions.add_experimental_option("detach", True)
    driver.close()
    set_did(param_did, param_did2, param_did3, param_did4, param_did5)



def restart_program():  # 重启程序
    python = sys.executable
    os.execl(python, python, *sys.argv)


def __intro():
    # root.mainloop()
    # print()
    # print("|  %s (v%s %s)" % (INFO["name"], INFO["version"], INFO["publishDate"]))
    # print("|  本程序由%s提供, %s, 喜欢的话可以给个star >_<" % (INFO["author"], INFO["repository"]))
    # print()
    thread_it(__openchrome())
    # driver = webdriver.Chrome()
    # driver.get("https://live.kuaishou.com/v/hot/")
    # name = driver.find_element_by_xpath('//*[@id="app"]/div[1]/div[1]/header/div/div[2]/div[3]/a/span')
    # name_title = name.get_attribute('title')
    # # cookie= driver.get_cookies()
    # while name_title == "":
    #     print("你还没有登录,请登录!!!")
    #     time.sleep(10)
    #     name = driver.find_element_by_xpath('//*[@id="app"]/div[1]/div[1]/header/div/div[2]/div[3]/a/span')
    #     name_title = name.get_attribute('title')
    # # 打印cookie信息
    # print("你已经登录,登录名:" + name_title)
    # cookie = driver.get_cookies()
    # driver.get("https://live.kuaishou.com/u/G338217245/3xjz7rnjnh6hjts")
    # cookie = [item['value'] for item in driver.get_cookies()]
    # cookie1 = [item['name'] for item in driver.get_cookies()]
    # # cookie = [item['name'] + '=' + item['value'] for item in driver.get_cookies()]
    # print(cookie)
    # print(cookie1)
    # param_did = cookie[4]
    # #param_did1 = cookie[1]
    # #param_did2 = cookie[2]
    # #param_did3 = cookie[7]
    # param_did2 = cookie[1]
    # param_did3 = cookie[0]
    # param_did4 = cookie[7]
    # param_did5 = cookie[2]
    # # param_kuaishou.live.web_st = cookie[1]
    # driver.get("https://live.kuaishou.com/v/hot/")
    # # param_did = "123"
    # #print(driver.title)  # 在编辑器的终端可以看到网站的标题打印出来
    # #driver.quit()  # 关闭Chrome浏览器，如果不写这句话浏览器就会停留在百度首页在后台运行不会关闭浏览器
    # set_did(param_did, param_did2, param_did3, param_did4, param_did5)


def thread_it(func, *args):
    '''将函数打包进线程'''
    # 创建
    t = threading.Thread(target=func, args=args)
    # 守护 !!!
    t.setDaemon(True)
    # 启动
    t.start()
    # 阻塞--卡死界面！
    # t.join()
def one_click_access():
    global click_access
    click_access = 1
    thread_it(__init__, )


def one_click_access2():
    if not os.path.exists("uid.txt"):
        open("uid.txt", "w")
    payload = {"operationName": "FollowQuery",
               "variables": {"count": 999,"pcursor":""},
               "query": "query FollowQuery($pcursor: String, $count: Int) {\n  allFollows(pcursor: $pcursor, count: $count) {\n    list {\n      id\n      name\n      living\n      avatar\n      sex\n      description\n      counts {\n        fan\n        follow\n        photo\n        __typename\n      }\n      __typename\n    }\n    pcursor\n    __typename\n  }\n}\n"}
    # payload = {"operationName": "privateFeedsQuery",
    #            "variables":{"principalId":uid,"pcursor":"","count":99999},
    #            "query": "query privateFeedsQuery($principalId: String, $pcursor: String, $count: Int) {\n  privateFeeds(principalId: $principalId, pcursor: $pcursor, count: $count) {\n    pcursor\n    list {\n      id\n      thumbnailUrl\n      poster\n      workType\n      type\n      useVideoPlayer\n      imgUrls\n      imgSizes\n      magicFace\n      musicName\n      caption\n      location\n      liked\n      onlyFollowerCanComment\n      relativeHeight\n      timestamp\n      width\n      height\n      counts {\n        displayView\n        displayLike\n        displayComment\n        __typename\n      }\n      user {\n        id\n        eid\n        name\n        avatar\n        __typename\n      }\n      expTag\n      __typename\n    }\n    __typename\n  }\n}\n"}
    res = requests.post(DATA_URL, headers=__headers_web, json=payload)
    # print(uid)
    # print(res.text)
    works = json.loads(res.content.decode(encoding='utf-8', errors='strict'))['data']['allFollows']['list']
    #print(len(works))
    #print(works[0])
    #gz_list = len(works)
    #print(gz_list)
    # if not os.path.exists("gz_uid.txt"):
    #     open("gz_uid.txt", "w")
    # gz_text = open("gz_uid.txt", "w+")
    # print(works[0]['id'] + "\n")
    # for gz in range(len(works)):
    #     gz_text.write(str(works[gz]['id']) + "\n")
    # gz_text.close()
    if json.loads(res.content.decode(encoding='utf-8', errors='strict'))['data']['allFollows']['pcursor'] != "":
        payload = {"operationName": "FollowQuery",
                   "variables": {"count": 999, "pcursor": "1017"},
                   "query": "query FollowQuery($pcursor: String, $count: Int) {\n  allFollows(pcursor: $pcursor, count: $count) {\n    list {\n      id\n      name\n      living\n      avatar\n      sex\n      description\n      counts {\n        fan\n        follow\n        photo\n        __typename\n      }\n      __typename\n    }\n    pcursor\n    __typename\n  }\n}\n"}
        # payload = {"operationName": "privateFeedsQuery",
        #            "variables":{"principalId":uid,"pcursor":"","count":99999},
        #            "query": "query privateFeedsQuery($principalId: String, $pcursor: String, $count: Int) {\n  privateFeeds(principalId: $principalId, pcursor: $pcursor, count: $count) {\n    pcursor\n    list {\n      id\n      thumbnailUrl\n      poster\n      workType\n      type\n      useVideoPlayer\n      imgUrls\n      imgSizes\n      magicFace\n      musicName\n      caption\n      location\n      liked\n      onlyFollowerCanComment\n      relativeHeight\n      timestamp\n      width\n      height\n      counts {\n        displayView\n        displayLike\n        displayComment\n        __typename\n      }\n      user {\n        id\n        eid\n        name\n        avatar\n        __typename\n      }\n      expTag\n      __typename\n    }\n    __typename\n  }\n}\n"}
        res1 = requests.post(DATA_URL, headers=__headers_web, json=payload)
        # print(uid)
        # print(res.text)
        works1 = json.loads(res1.content.decode(encoding='utf-8', errors='strict'))['data']['allFollows']['list']
        #print(len(works1))
        # print(works[0])
        # gz_list = len(works1)
        # # print(gz_list)
        # gz_text = open("gz_uid.txt", "w+")
        # print(works1[0]['id'] + "\n")
        # for gz in range(len(works1)):
        #     gz_text.write(str(works1[gz]['id']) + "\n")
        # gz_text.close()
    works_uid = works + works1
    gz_list = len(works_uid)
    # print(gz_list)
    gz_text = open("uid.txt", "w+")
    gz_text.truncate(0)
    #print(works_uid[0]['id'] + "\n")
    text.insert(END, "正在获取uid中,请稍等..." )
    text.update()
    text.see(END)
    for gz in range(len(works_uid)):
        gz_text.write(str(works_uid[gz]['id']) + "\n")
    gz_text.close()
    text.insert(END, "获取并写入uid.txt成功..." )
    text.update()
    text.see(END)
    if os.path.exists("uid_log.txt"):
        delete_uid_log = tkinter.messagebox.askokcancel('提示', '你要删除uid_log.txt吗?删除uid_log.txt代表重新重头下载!')
        if delete_uid_log == True:
            if (os.path.exists("uid_log.txt")):
                text.insert(END, "正在删除uid_log.txt...")
                text.update()
                text.see(END)
                os.remove("uid_log.txt")
                text.insert(END, "uid_log.txt删除成功...")
                text.update()
                text.see(END)
        else:
            tkinter.messagebox.showinfo('提示', '看来你不愿意重新重头开始下载!')
    else:
        tkinter.messagebox.showinfo('提示', 'uid_log.txr不存在!')
    if os.path.exists("list_num.txt"):
        delete_uid_log = tkinter.messagebox.askokcancel('提示', '你要删除list_num.txt吗?删除list_num.txt代表重新重头下载!')
        if delete_uid_log == True:
            if (os.path.exists("list_num.txt")):
                text.insert(END, "正在删除list_num.txt...")
                text.update()
                text.see(END)
                os.remove("list_num.txt")
                text.insert(END, "list_num.txt删除成功...")
                text.update()
                text.see(END)
        else:
            tkinter.messagebox.showinfo('提示', '看来你不愿意重新重头开始下载!')
    else:
        tkinter.messagebox.showinfo('提示', 'list_num.txr不存在!')

def stop():
    """Stop scanning by setting the global flag to False."""
    QJ.stop = True
    text.insert(END, "正在跳过当前用户...")
    text.update()
    text.see(END)

def save_config_jb():
    config = configparser.ConfigParser()
    config.read('.\\config.ini')
    if config.has_section('基本设置') == False:
        config.add_section('基本设置')

    config.set('基本设置','自动模式',str(var2.get()))
    config.set('基本设置','延时',entry.get())
    config.set('基本设置', '已存在次数', entry2.get())
    config.set('基本设置', '自动跳过', str(var.get()))

    o = open('.\\config.ini', 'w')
    config.write(o)
    o.close()  # 不要忘记关闭
    tkinter.messagebox.showinfo('提示', '保存配置后下次启动时生效!!!')


root = Tk()   #生成一个主窗口对象
root.title('快手批量下载') #标题
root.geometry('600x688+600+200') #大小位置

if not os.path.exists('.\\config.ini'):
    # print("创建预设文件 uid ...")
    open('.\\config.ini', "w")
if not os.path.getsize('.\\config.ini'):
    config = configparser.ConfigParser()
    config.read('.\\config.ini')
    print(config.has_section('基本设置'))
    if config.has_section('基本设置') == False:
        config.add_section('基本设置')
        config.set('基本设置', '自动模式', '0')
        config.set('基本设置', '延时', '8')
        config.set('基本设置', '已存在次数', '20')
        config.set('基本设置', '自动跳过', '0')
    o = open('.\\config.ini', 'w')
    config.write(o)
    o.close()  # 不要忘记关闭

config = configparser.ConfigParser()
config.read('.\\config.ini')

# print('sections:', ' ', config.sections())
#
# # -options(section)得到该section的所有option
# print('options:', ' ', config.options('config'))
#
# # -items（section）得到该section的所有键值对
# print('items:', ' ', config.items('cmd'))
#
# # -get(section,option)得到section中option的值，返回为string类型
# print('get:', ' ', config.get('cmd', 'startserver'))
#
# # -getint(section,option)得到section中的option的值，返回为int类型
# print('getint:', ' ', config.getint('cmd', 'id'))
# print('getfloat:', ' ', config.getfloat('cmd', 'weight'))
# print('getboolean:', '  ', config.getboolean('cmd', 'isChoice'))
# """
# 首先得到配置文件的所有分组，然后根据分组逐一展示所有
# """
#
# for sections in config.sections():
#     for items in config.items(sections):
#         print(items)

config.items('基本设置')



text = Listbox(root,width=85,height=30)
text.grid(row=0,columnspan=3)

# button=Button(root,text="1.初始",width=10,command=lambda :thread_it(__init__, ))
# button.grid(row=5,column=0,sticky=W)

var2 = IntVar()
Checkbutton2 = Checkbutton(root,text="自动模式",  variable=var2)
Checkbutton2.grid(row=1,column=0,sticky=W)
if config.getint('基本设置', '自动模式') == 1:
    Checkbutton2.select()
    thread_it(__init__, )

button5=Button(root,text="保存配置",width=20,command=lambda :thread_it(save_config_jb(), ))
button5.grid(row=1,column=2,sticky=E)

label = Label(root,text='请输入延时时间:')
label.grid(row=2,sticky=W)

entry = Entry(root,width=10)
entry.grid(row=2,column=1,sticky=W)
entry.insert(0,config.get('基本设置', '延时'))


label2 = Label(root,text='请输入已存在出现次数方便自动跳过:')
label2.grid(row=3,column=0,sticky=W)

entry2 = Entry(root,width=10)
entry2.grid(row=3,column=1,sticky=W)
entry2.insert(0,config.get('基本设置', '已存在次数'))

var = IntVar()
Checkbutton = Checkbutton(root,text="自动跳过当前,执行下一个用户",  variable=var)
Checkbutton.grid(row=3,column=2)
if config.getint('基本设置', '自动跳过') == 1:
    Checkbutton.select()

button4=Button(root,text="一键跳过当前用户",width=20,command=lambda :thread_it(stop, ))
button4.grid(row=6,column=0,sticky=W)

button1=Button(root,text="一键获取关注uid",width=20,command=lambda :thread_it(one_click_access, ))
button1.grid(row=6,column=2,sticky=E)

button1=Button(root,text="开始",width=20,command=lambda :thread_it(__init__, ))
button1.grid(row=7,column=0,sticky=W)

button2=Button(root,text="退出",width=20,command=root.quit)
button2.grid(row=7,column=2,sticky=E)

root.mainloop()